package com.kexio.auth.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 灵活的多租户模式配置属性
 * 
 * 支持多种租户模式的统一配置：
 * 1. 租户开关控制
 * 2. 多数据源模式（租户关闭时）
 * 3. 行级多租户模式
 * 4. 实例级多租户模式
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@ConfigurationProperties(prefix = "kexio.auth.tenant")
public class TenantModeProperties {

    /**
     * 租户功能总开关
     */
    private boolean enabled = false;

    /**
     * 租户模式类型
     */
    private TenantMode mode = TenantMode.DISABLED;

    /**
     * 默认租户ID（当租户模式关闭时使用）
     */
    private String defaultTenant = "default";

    /**
     * 多数据源配置（租户关闭时使用）
     */
    private MultiDataSourceConfig multiDataSource = new MultiDataSourceConfig();

    /**
     * 行级租户配置
     */
    private RowLevelConfig rowLevel = new RowLevelConfig();

    /**
     * 实例级租户配置
     */
    private InstanceLevelConfig instanceLevel = new InstanceLevelConfig();

    /**
     * 租户模式枚举
     */
    public enum TenantMode {
        /**
         * 禁用租户功能 - 支持多数据源
         */
        DISABLED,
        
        /**
         * 行级多租户 - 同一数据库，通过 tenant_id 字段隔离
         */
        ROW_LEVEL,
        
        /**
         * 实例级多租户 - 每个租户独立数据库实例
         */
        INSTANCE_LEVEL,
        
        /**
         * 混合模式 - 支持行级和实例级并存
         */
        HYBRID
    }

    /**
     * 多数据源配置（租户功能关闭时）
     */
    public static class MultiDataSourceConfig {
        /**
         * 是否启用多数据源
         */
        private boolean enabled = true;
        
        /**
         * 默认数据源名称
         */
        private String primary = "master";
        
        /**
         * 数据源选择策略
         */
        private DataSourceStrategy strategy = DataSourceStrategy.HEADER;
        
        /**
         * 数据源映射规则
         */
        private Map<String, String> mapping = new HashMap<>();

        public enum DataSourceStrategy {
            /**
             * 通过请求头选择数据源
             */
            HEADER,
            
            /**
             * 通过请求参数选择数据源  
             */
            PARAMETER,
            
            /**
             * 通过用户属性选择数据源
             */
            USER_ATTRIBUTE,
            
            /**
             * 自定义策略
             */
            CUSTOM
        }

        // Getters and Setters
        public boolean isEnabled() { return enabled; }
        public void setEnabled(boolean enabled) { this.enabled = enabled; }
        
        public String getPrimary() { return primary; }
        public void setPrimary(String primary) { this.primary = primary; }
        
        public DataSourceStrategy getStrategy() { return strategy; }
        public void setStrategy(DataSourceStrategy strategy) { this.strategy = strategy; }
        
        public Map<String, String> getMapping() { return mapping; }
        public void setMapping(Map<String, String> mapping) { this.mapping = mapping; }
    }

    /**
     * 行级租户配置
     */
    public static class RowLevelConfig {
        /**
         * 租户字段名
         */
        private String tenantColumn = "tenant_id";
        
        /**
         * 忽略租户过滤的表
         */
        private List<String> ignoreTables = new ArrayList<>();
        
        /**
         * 是否启用严格模式（无租户ID时抛异常）
         */
        private boolean strictMode = true;
        
        /**
         * 是否自动注入租户ID到INSERT语句
         */
        private boolean autoFillTenantId = true;

        // Getters and Setters
        public String getTenantColumn() { return tenantColumn; }
        public void setTenantColumn(String tenantColumn) { this.tenantColumn = tenantColumn; }
        
        public List<String> getIgnoreTables() { return ignoreTables; }
        public void setIgnoreTables(List<String> ignoreTables) { this.ignoreTables = ignoreTables; }
        
        public boolean isStrictMode() { return strictMode; }
        public void setStrictMode(boolean strictMode) { this.strictMode = strictMode; }
        
        public boolean isAutoFillTenantId() { return autoFillTenantId; }
        public void setAutoFillTenantId(boolean autoFillTenantId) { this.autoFillTenantId = autoFillTenantId; }
    }

    /**
     * 实例级租户配置
     */
    public static class InstanceLevelConfig {
        /**
         * 租户数据源映射策略
         */
        private TenantDataSourceStrategy strategy = TenantDataSourceStrategy.TENANT_ID_MAPPING;
        
        /**
         * 租户到数据源的映射
         */
        private Map<String, String> tenantDataSourceMapping = new HashMap<>();
        
        /**
         * 数据源命名规则（当使用模式匹配时）
         */
        private String dataSourceNamingPattern = "tenant_{tenantId}";
        
        /**
         * 是否支持动态创建数据源
         */
        private boolean dynamicCreation = false;

        public enum TenantDataSourceStrategy {
            /**
             * 租户ID直接映射到数据源名
             */
            TENANT_ID_MAPPING,
            
            /**
             * 使用命名模式生成数据源名
             */
            NAMING_PATTERN,
            
            /**
             * 自定义映射规则
             */
            CUSTOM_MAPPING
        }

        // Getters and Setters
        public TenantDataSourceStrategy getStrategy() { return strategy; }
        public void setStrategy(TenantDataSourceStrategy strategy) { this.strategy = strategy; }
        
        public Map<String, String> getTenantDataSourceMapping() { return tenantDataSourceMapping; }
        public void setTenantDataSourceMapping(Map<String, String> tenantDataSourceMapping) { 
            this.tenantDataSourceMapping = tenantDataSourceMapping; 
        }
        
        public String getDataSourceNamingPattern() { return dataSourceNamingPattern; }
        public void setDataSourceNamingPattern(String dataSourceNamingPattern) { 
            this.dataSourceNamingPattern = dataSourceNamingPattern; 
        }
        
        public boolean isDynamicCreation() { return dynamicCreation; }
        public void setDynamicCreation(boolean dynamicCreation) { this.dynamicCreation = dynamicCreation; }
    }

    // Main class Getters and Setters
    public boolean isEnabled() { return enabled; }
    public void setEnabled(boolean enabled) { this.enabled = enabled; }
    
    public TenantMode getMode() { return mode; }
    public void setMode(TenantMode mode) { this.mode = mode; }
    
    public String getDefaultTenant() { return defaultTenant; }
    public void setDefaultTenant(String defaultTenant) { this.defaultTenant = defaultTenant; }
    
    public MultiDataSourceConfig getMultiDataSource() { return multiDataSource; }
    public void setMultiDataSource(MultiDataSourceConfig multiDataSource) { this.multiDataSource = multiDataSource; }
    
    public RowLevelConfig getRowLevel() { return rowLevel; }
    public void setRowLevel(RowLevelConfig rowLevel) { this.rowLevel = rowLevel; }
    
    public InstanceLevelConfig getInstanceLevel() { return instanceLevel; }
    public void setInstanceLevel(InstanceLevelConfig instanceLevel) { this.instanceLevel = instanceLevel; }

    @Override
    public String toString() {
        return "TenantModeProperties{" +
                "enabled=" + enabled +
                ", mode=" + mode +
                ", defaultTenant='" + defaultTenant + '\'' +
                ", multiDataSource=" + multiDataSource +
                ", rowLevel=" + rowLevel +
                ", instanceLevel=" + instanceLevel +
                '}';
    }
}
